package com.huang.day6;

import org.junit.jupiter.api.Test;

import javax.swing.plaf.ViewportUI;
import java.lang.annotation.Target;
import java.util.LinkedList;
import java.util.concurrent.locks.LockSupport;

/**
 * @author HuangShen
 * @Description
 * @create 2021-04-05 6:53
 */
public class MyTest {
    static final Object lock = new Object();


    @Test
    public void test1() {
        synchronized (lock) {

            try {
                lock.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    @Test
    public void test2() {
        new Thread(() -> {
            synchronized (lock) {
                System.out.println("进入t1线程");
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t1被唤醒");
            }
        }, "t1").start();

        new Thread(() -> {
            synchronized (lock) {
                System.out.println("进入t2线程");
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t2被唤醒");
            }
        }, "t2").start();


        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (lock) {
//            lock.notify();

            lock.notifyAll();


        }


    }


    @Test
    public void test3() {
        MessageQueue messageQueue = new MessageQueue(2);

        for (int i = 0; i < 3; i++) {

            int id=i;
            new Thread(() -> {
                while (true){

                    messageQueue.put(new Message(id,"消息"+id));
                    System.out.println("生产者"+id+"放入消息");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }, "生产者线程"+i).start();
        }

        new Thread(()->{
            while (true){

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                Message take = messageQueue.take();
                System.out.println("消费者取出消息"+take);
            }

        }, "消费者线程").start();



    }

    @Test
    public void test4(){
        LockSupport.park();

    }


}

//超时效果 保护性暂停
class GuardedObject {

    private Object respond;


    public Object getRespond(long timeout) {

        synchronized (this) {
            long startTime = System.currentTimeMillis();
            long passedTime = 0;
            while (respond == null) {
                long waitTime = timeout - passedTime;
                if (waitTime < 0) {
                    break;
                }
                try {
                    this.wait(waitTime);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                passedTime = System.currentTimeMillis() - startTime;
            }

            return respond;
        }


    }
}

//线程间通讯
class MessageQueue {


    private LinkedList<Message> messages = new LinkedList<>();
    private int capcity;

    public MessageQueue(int capcity) {
        this.capcity = capcity;
    }

    //取出消息
    public Message take() {


        synchronized (messages) {
            while (messages.isEmpty()) {
                try {
                    System.out.println("消息队列为空,进入等待");
                    this.messages.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.capcity--;
            Message message = this.messages.removeFirst();
            this.messages.notifyAll();
            return message;
        }
    }


    //放入消息
    public void put(Message message) {

        synchronized (messages){
            while (this.messages.size()==capcity){
                try {
                    System.out.println("消息队列已满");
                   this.messages.wait();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.messages.addLast(message);
            this.capcity++;
            this.messages.notifyAll();
        }
    }

}

final class Message {
    private int id;
    private Object value;


    public Message(int id, Object value) {
        this.id = id;
        this.value = value;
    }

    public int getId() {
        return id;
    }

    public Object getValue() {
        return value;
    }

    @Override
    public String toString() {
        return "Message{" +
                "id=" + id +
                ", value=" + value +
                '}';
    }
}